#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstdio>
#include <cstring>
#include <string>

using namespace std;

// int main()
// {
//     //第一步，创建管道文件，打开读写端
//     int fds[2];
//     int n = pipe(fds);
//     if(n != 0)
//     {
//         perror("pipe");
//         exit(-1);
//     }
//     //第二步 创建子进程
//     pid_t id = fork();
//     if(id == -1)
//     {
//         perror("fork");
//         exit(-1);
//     }
//     else if(id == 0)
//      {
//         //子进程进行写入
//         close(fds[0]);
//         //子进程通信代码
//         const char* s = "你好，我是子进程";
//         int cnt = 0;
//         while(true)
//         {
//             char buffer[1024];      //这个缓冲区只有子进程可以看到
//             snprintf(buffer,sizeof buffer,"child->parent say:%s[%d] pid：%d",s,++cnt,getpid());
//             //写端写满时，再写会阻塞，等待对方进行读取
//             write(fds[1],buffer,strlen(buffer));     //把缓冲区内容写到管道里
//             cout << "cout: " << cnt << endl;
//             sleep(1);       //每隔1秒写入一次
//         }

//         //子进程
//         exit(0);
//      }
//     //     //父进程进行读取
//     close(fds[1]);
//     //父进程通信代码
//     while(true)
//     {
//         char buffer[1024];
//         //如果管道中没数据，默认会直接阻塞当前正在读取的进程
//         ssize_t s = read(fds[0],buffer,sizeof(buffer)-1);       //从管道往缓冲区里读数据
//         if(s > 0)
//             buffer[s] = 0;      //给末尾加个\0
//         cout<<"#"<< buffer<< "| parent pid:"<< getpid()<<endl;
//         // 父进程没有sleep
//     }
//     n = waitpid(id,nullptr,0);      
//     if(n != id)
//     {
//         perror("waitpid");
//         exit(-1);
//     }
//     return 0;
// }
int main()
{
    //第一步，创建管道文件，打开读写端
    int fds[2];
    int n = pipe(fds);
    if(n != 0)
    {
        perror("pipe");
        exit(-1);
    }
    //第二步 创建子进程
    pid_t id = fork();
    if(id == -1)
    {
        perror("fork");
        exit(-1);
    }
    else if(id == 0)
     {
        //子进程读取
        close(fds[1]);
        //子进程通信代码
        while(true)
        {
            char buffer[1024];
            //如果管道中没数据，默认会直接阻塞当前正在读取的进程
            ssize_t s = read(fds[0],buffer,sizeof(buffer)-1);       //从管道往缓冲区里读数据
            if(s > 0)
                buffer[s] = 0;      //给末尾加个\0
            cout<<"#"<< buffer<< "|  pid:"<< getpid()<<endl;
        }
        //子进程
        exit(0);
     }
    //父进程写入
    close(fds[0]);
    //父进程通信代码
    const char* s = "i am father";
    int cnt = 0;
    while(true)
    {
        char buffer[1024];      
        snprintf(buffer,sizeof buffer,"parent->child say:%s[%d] pid：%d",s,++cnt,getpid());
        //写端写满时，再写会阻塞，等待对方进行读取
        write(fds[1],buffer,strlen(buffer));     //把缓冲区内容写到管道里
        cout << "num: " << cnt << endl;
        sleep(1);       //每隔1秒写入一次
    }
 
    n = waitpid(id,nullptr,0);      
    if(n != id)
    {
        perror("waitpid");
        exit(-1);
    }
    return 0;
}